<?php

namespace App\Console\Commands;


use App\Models\Event;
use App\Models\Order;
use App\Models\OrderMoney;
use App\Models\User;
use App\Models\UserAuth;
use App\Models\UserProfit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;


class CheckOrderCommand extends Command
{
    /**
     * check-order 每天订单检查处理（可以重复执行）
     *
     * 请求：
     *  php artisan command:check-order
     *  sudo -u www php /www/wwwroot/slh/laravel.test/artisan command:check-order
     *  sudo -u www php /www/wwwroot/shenlanhui/laravel/artisan command:check-order
     *
     */
    /**
     * 参数与选项的区别
     *      在执行命令时，参数必须严格按定义时的顺序输入，不需输入参数名，只需输入参数的值即可。
     *      输入选项则必须带选项名，且选项名前须加 -- 前缀（选项简写字母前加 -），选项可按任意顺序输入
     */

    // 请求 以及参数
    // protected $signature = 'command:name {param1} {param2}';  // 必填参数
    // protected $signature = 'command:name {参数名?} {参数名=默认值} {参数名? : 参数说明}';  // 可选参数
    // protected $signature = 'command:name {--选项名} {--选项名=} {--选项名=默认值} {--简写字母|选项名} {--选项名 : 选项说明}';  // 选项
    protected $signature = 'command:check-order';


    protected $description = '每天订单检查处理：处理用户订单状态，以及订单收益等信息';

    public function __construct()
    {
        parent::__construct();
    }

    // 认证用户处理
    public function handle()
    {
        // 昨天的时间
        $beginYesday = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'));
        $endYesday   = mktime(0, 0, 0, date('m'), date('d'), date('Y')) - 1;

        // 检查每天到期活动
        $this->comment('获取昨天到期的活动');
        $profitDb = new UserProfit();
        $userDb   = new User();
        $orderDb  = new Order();
        $eventDb  = new Event();
        $events   = $eventDb->where('dead_time', '>=', $beginYesday)->where('dead_time', '<=', $endYesday)->get()->toArray();
        if(empty($events)){
            return $this->error('没有需要处理的活动');
        }

        // 查询这些活动的订单
        $this->comment('获取昨天到期活动的所有的订单');
        $eIds   = array_column($events, 'id');
        $orders = $orderDb->whereIn('event_id', $eIds)->get()->toArray();
        if(empty($orders)){
            return $this->error('没有需要处理的订单');
        }

        // 查询这些活动的提成
        $this->comment('获取昨天到期活动订单的提成');
        $oIds    = array_column($orders, 'id');
        $profits = $profitDb->whereIn('order_id', $oIds)->get()->toArray();
        if(empty($profits)){
            return $this->error('没有需要处理的订单提成');
        }

        // 整理用户提成数据
        $userMoney = [];
        foreach($profits as $_profit){
            $userMoney[$_profit['uid']] = ($userMoney[$_profit['uid']] ?? 0) + $_profit['profit'];
        }

        // 保存信息
        DB::beginTransaction();
        try{
            // 将订单状态设置为已经结束
            $res = $orderDb->whereIn('event_id', $eIds)->update(['is_over' => 1]);

            // 将活动冻结资金转换为一般资金
            foreach($userMoney as $_uid => $_money){
                // 进行锁表操作
                $user = $userDb->where('id', $_uid)->lockForUpdate()->first();

                $userData = ['money' => DB::raw("money+".$_money), 'money_freeze' => DB::raw("money_freeze-".$_money),];
                $userDb->where('id', $_uid)->where('money_freeze', '>=', $_money)->update($userData);
            }


            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->error($e->getMessage());
        }


        // 完成
        $this->line('完成');

        return true;
    }


}
